<!--
  @anthor: darker,
  @description: 图片/文件上传，集合图片/文件，单/多文件上传于一体,涵盖图片回显及相关动态操作 为适应不同场景提供了多个主题形式
  @date: 2020 / 07 / 17,
  @remark:
 -->
<!--   上传附件组件
引用示例：
<uploadFile :fileList="fileList" accept="file" uploadUrl="http://whhs.zhdj360.cn/stddj-api/api/common/fileUpload/uploadBlob" :multiple="true" theme="picture-card" :fileList.sync="fileList"></uploadFile>
参数详解：
multiple ==== 是否为多文件
limit ==== 文件数量 默认为10
disabledInput ==== 开关  用户是否禁用
uploadUrl ==== 上传地址 默认为当前项目代理域名下的/stddj-api/api/common/fileUpload/uploadBlob请求接口
fileList ====  传入文件列表 用于回显
accept ==== 文件过滤  image ->> 图片类型文件  file ->> 所有文件类型
theme ==== 主题  本插件提供(text/picture/picture-card)三种模式 为匹配不同应用场景

***************************
    module                       模块名  用于后端保存   必传  传模块拼音 例如：三会一课 -- sanhuiyike
    isBut                        是否隐藏上传按钮  默认显示         传true为隐藏
    isView                       是否可以点击来预览  默认可以  传true为隐藏
    isDelete                     是否隐藏删除按钮  默认显示         传true为隐藏
    isDownLoad                   是否隐藏下载按钮  默认显示         传true为隐藏
    defaultFileList              回显  传入：[{fileName: '', fileSize: '', url: '', dcsUrl: ''}]
    accept                       上传文件类型     默认不限制    例如： .jpg,.jpeg,.png,.gif
    maxSize                      最大上传大小   默认和最大 音视频 500M   文档 30M   数值单位为k
    params                       上传附带的参数
    title                        标题  不传不显示
    width                        组件宽度，如果是具体数值，记得传单位   默认 400px

    事件
    setFileList                  重置文件列表  传入：[{fileName: '', fileSize: '', url: '', dcsUrl: ''}]  --主动来触发该事件，用于回显
                                例：this.$refs.xxx.setFileList(arr)  arr 为要回显的文件列表
    upload                       返回所有文件列表  格式： [{fileName: '', fileSize: '', url: '', dcsUrl: '', fileExt: '', fileSizeStr: ''}] -- 上传后的返回事件

    数据
    fileName                     文件名称     必传
    fileSize                     文件大小
    url                          文件相对路径  必传
    dcsUrl                       文件预览路径

 -->
<template>
  <div class="upload-container">
    <el-dialog
      :visible.sync="dialogVisibleImg"
      :title="ImgName"
      size="tiny"
      :append-to-body="true"
    >
      <img width="100%" :src="dialogImageUrl" alt="" />
    </el-dialog>
    <el-upload
      :class="[disabledInput ? 'upLoadShowNone upload-demo' : 'upload-demo']"
      name="fileObj"
      :accept="acceptType()"
      action="string"
      :headers="myheaders"
      :multiple="multiple"
      :on-remove="handleRemove"
      :on-success="handleSuccess"
      :before-upload="validDoc"
      :on-preview="handlePictureCardPreview"
      :disabled="disabledInput"
      :list-type="theme"
      :http-request="httpRequest"
      :show-file-list="false"
      v-show="handleShowBtn()"
      :limit="limit"
    >
      <!-- :file-list="fileList" -->
      <i
        class="el-icon-plus avatar-uploader-icon"
        v-if="theme == 'picture-card'"
      ></i>
      <el-button v-else size="medium" icon="el-icon-upload">点击上传</el-button>
      <slot name="slot"></slot>
    </el-upload>
    <!-- 文件列表显示 -->
    <div
      class="upload-file-main"
      v-if="fileListTest && fileListTest.length > 0"
    >
      <div
        class="upload-file-item"
        v-for="(item, index) in fileListTest"
        :key="index"
      >
        <div
          class="upload-file-pic"
          :style="!isView ? { cursor: 'pointer' } : {}"
          @click="viewFile(item)"
        >
          <img
            v-if="handleFileIcon(item) === 'doc'"
            src="../../assets/resource/word.png"
          />
          <img
            v-if="handleFileIcon(item) === 'xls'"
            src="../../assets/resource/Rexcel.png"
          />
          <img
            v-if="handleFileIcon(item) === 'ppt'"
            src="../../assets/resource/PowerPoint.png"
          />
          <img
            v-if="handleFileIcon(item) === 'pdf'"
            src="../../assets/resource/pdf.png"
          />
          <img
            v-if="handleFileIcon(item) === 'txt'"
            src="../../assets/resource/txt.png"
          />
          <img
            v-if="handleFileIcon(item) === 'media'"
            src="../../assets/resource/media.png"
          />
          <img
            v-if="handleFileIcon(item) === 'other'"
            src="../../assets/resource/word.png"
          />
        </div>
        <div
          class="upload-file-mid"
          :style="!isView ? { cursor: 'pointer' } : {}"
          @click="viewFile(item)"
        >
          <div class="upload-file-name" v-text="item.name"></div>
          <div class="upload-file-size" v-show="item.size">
            {{ (item.size / 1024).toFixed(1) }}k
          </div>
        </div>
        <div
          class="upload-file-right"
          v-if="isDownLoad"
          @click="downloadFile(item)"
        >
          <span>下载</span>
        </div>
        <div
          class="upload-file-right"
          v-if="!isDelete"
          @click="delFile(item, index)"
        >
          <span>删除</span>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
var token = localStorage.getItem("token") || ""; // 获取token
export default {
  name: "UploadFile",
  props: {
    //是否为多文件
    multiple: {
      type: Boolean,
      default: false
    },
    limit: {
      type: Number,
      default: 10
    },
    // 开关 是否禁用 禁用后 无法删除与上传
    disabledInput: {
      type: Boolean,
      default: false
    },
    // 文件上传地址
    uploadUrl: {
      type: String,
      default: `/api/py-common/file/upload`
    },
    // 文件列表 用于回显
    fileList: {
      type: Array,
      default: function() {
        return [];
      }
    },
    // 文件过滤 image -- 图片类型文件  file -- 所有文件类型
    accept: {
      type: String,
      default: "image"
    },
    // 主题 适应不通场景 （text/picture/picture-card）
    theme: {
      type: String,
      default: "picture-card"
    },
    //控制上传图片或者文件大小
    fileSize: {
      type: Number,
      default: 2
    },
    isView: {
      type: Boolean,
      default: false //默认false 为可以预览   true为隐藏
    },
    isDownLoad: {
      type: Boolean,
      default: true
    },
    isDelete: {
      type: Boolean,
      default: true
    },
    isBut: {
      type: Boolean,
      default: false
    },
    maxSize: {
      type: Number,
      default: 30
    }
  },
  data() {
    return {
      dialogVisibleImg: false,
      isViewing: false,
      ImgName: "",
      dialogImageUrl: "",
      myheaders: {
        Authorization: token
      },
      mediaList: [
        "mp3",
        "aac",
        "mp4",
        "ape",
        "flac",
        "wav",
        "wma",
        "amr",
        "mid",
        "mp4",
        "m4v",
        "3gp",
        "mpg",
        "flv",
        "f4v",
        "swf",
        "avi",
        "gif",
        "wmv",
        "rmvb",
        "mov",
        "mts",
        "m2t",
        "webm",
        "ogg",
        "mkv"
      ], // 音视频格式，用于判断是否音视频
      fileListTest: []
    };
  },
  computed: {},
  methods: {
    // 匹配上传的文件类型---image/file
    acceptType() {
      if (this.accept == "image") {
        return `image/*`;
      } else if (this.accept == "pdf") {
        return `.pdf`;
      } else if (this.accept == "rar") {
        return `.rar`;
      } else if (this.accept == "xls,xlsx") {
        return `.xls,.xlsx`;
      } else {
        return `.xls,.xlsx,.doc,.docx,.ppt,.pptx,.pdf,.txt,.mp3,.3gp,.mp4,.avi`;
      }
    },
    handleShowBtn() {
      if (this.isBut) {
        return false;
      } else {
        if (this.limit && this.fileListTest.length > this.limit) {
          return false;
        }
        return true;
      }
    },
    // 获取的是文件类型的文件列表
    handleSuccess(res, file, fileList) {
      let that = this;
      const currentPic = that.$baseData.filePath + res.url;
      fileList.map((item, index) => {
        if (item.name == file.name) {
          item = {};
          item.url = currentPic;
          item.fileName = res.fileName;
        }
      });
      // that.$emit("backcall", fileList);
    },
    handleRemove(file, fileList) {
      this.$emit("backcall", fileList);
    },
    // 图片预览
    handlePictureCardPreview(file) {
      let name = file.name || file.fileName;
      if (this.isImg(name)) {
        this.dialogImageUrl = file.url;
        this.dialogVisibleImg = true;
        this.ImgName = file.name;
      } else {
        window.open(file.url);
      }
    },
    handleFileIcon(item) {
      if (item && item.name) {
        let loc = item.name.lastIndexOf(".");
        let fileType = item.name.slice(loc + 1).toLowerCase();
        if (["doc", "docx"].includes(fileType)) {
          return "doc";
        } else if (["xls", "xlsx"].includes(fileType)) {
          return "xls";
        } else if (["ppt", "pptx"].includes(fileType)) {
          return "ppt";
        } else if (["pdf"].includes(fileType)) {
          return "pdf";
        } else if (["txt"].includes(fileType)) {
          return "txt";
        } else if (this.mediaList.includes(fileType)) {
          return "media";
        } else {
          return "other";
        }
      } else {
        return "other";
      }
    },
    // 删除文件
    delFile(item, index) {
      let _this = this;
      // _this.showConfirm(
      //   "确定删除该文件?",
      //   function() {
      //     let url = _this.fileList[index].url;
      //     _this.deleteFile(url, () => {
      //       _this.fileList.splice(index, 1);
      //       _this.$refs.upload.uploadFiles = JSON.parse(
      //         JSON.stringify(_this.fileList)
      //       );
      //       _this.$emit("upload", _this.fileList);
      //     });
      //   },
      //   null
      // );
    },
    // 点击下载文件
    downloadFile(file) {
      if (this.isDownLoad) {
        console.log("file", file);
        let f1 = document.createElement("a");
        f1.setAttribute("href", file.url);
        f1.setAttribute("download", file.name);
        document.body.appendChild(f1);
        f1.click();
        document.body.removeChild(f1);
      }
    },
    // 文件预览
    // 点击预览文件
    viewFile(file) {
      if (this.isViewing) {
        return false;
      }
      if (this.isView) {
        return false;
      }
      if (!file.url) {
        this.msgAlert("文件出错，请重新上传");
        return false;
      }
      this.isViewing = true;
      let data = {
        filePath: file.url,
        isTransform: 1
      };
      //  这里写预览逻辑，需要后台配合
      // this.$http.post(baseUploadFile.viewFile, data, result => {
      //   if (result.code === 0) {
      //     file["dcsUrl"] = result.data;
      //     this.isViewing = false;
      //     window.open(filePath + result.data);
      //   } else {
      //     this.isViewing = false;
      //     this.msgAlert(result.msg);
      //   }
      // });
    },
    // 图片/文件上传前的校验
    beforeUpload(file) {
      var testmsg = file.name.substring(file.name.lastIndexOf(".") + 1);
      const isLt10M = file.size / 1024 / 1024 < this.fileSize; //这里做文件大小限制
      if (!isLt10M) {
        this.$message({
          message: `上传文件大小不能超过 ${this.fileSize}MB!`,
          type: "error"
        });
      }
      return isLt10M;
      // let loc = file.name.lastIndexOf(".");
      // // 截取下标加1，去掉.
      // let fileType = file.name.slice(loc + 1).toLowerCase();
      // console.log(fileType);
      // if (this.acceptType() && this.acceptType().length > 0) {
      //   let acceptList = this.acceptType().split(",");
      //   acceptList = acceptList.map(i => {
      //     i = i.trim();
      //     return i;
      //   });
      //   if (!acceptList.includes(fileType)) {
      //     this.msgAlert(`只能上传${this.acceptType()}类型的文件`);
      //     return false;
      //   }
      // }
      // let maxSize = this.maxSize ? this.maxSize : 0;
      // if (this.mediaList.indexOf(fileType) < 0) {
      //   // 文件最大30M
      //   if (maxSize > 30720) {
      //     maxSize = 30720;
      //   }
      // } else {
      //   // 音视频最大500M
      //   if (maxSize > 512000) {
      //     maxSize = 512000;
      //   }
      // }
      // if (maxSize && file.size / 1024 > maxSize) {
      //   this.msgAlert(
      //     `文件大小超出限制！限制大小为${(maxSize / 1024).toFixed(2)}M`
      //   );
      //   return false;
      // }
    },
    // 上传文件之前的钩子
    validDoc(file) {
      let loc = file.name.lastIndexOf(".");
      // 截取下标加1，去掉.
      let fileType = file.name.slice(loc + 1).toLowerCase();
      if (this.fileListTest.length >= this.limit) {
        this.$message.error(
          `只能上传${this.limit}份文件，如需继续上传，请先删除已经上传的文件`
        );
        return;
      }
      if (this.acceptTypeStr && this.acceptTypeStr.length > 0) {
        let acceptList = this.acceptTypeStr.split(",");
        acceptList = acceptList.map(i => {
          i = i.trim();
          return i;
        });
        if (!acceptList.includes(fileType)) {
          this.$message.error(`只能上传${this.acceptTypeStr}类型的文件`);
          return false;
        }
      }
      let maxFileSize = file.size / 1024 / 1024 < this.fileSize; //这里做文件大小限制
      if (this.mediaList.indexOf(fileType) < 0) {
        // 文件最大30M
        if (!maxFileSize) {
          this.$message.error(`文件大小超出限制！限制大小为${this.fileSize}MB`);
          return false;
        }
      } else {
        // 音视频最大500M
        if (!maxFileSize) {
          this.$message.error(`文件大小超出限制！限制大小为${this.fileSize}MB`);
          return false;
        }
      }
      if (!maxFileSize) {
        this.$message.error(`文件大小超出限制！限制大小为${this.fileSize}MB`);
        return false;
      }
    },
    // 自定义上传
    httpRequest(params) {
      let that = this;
      let name = params.file.name;
      console.log("上传文件", params);
      // this.fileListTest.push(params.file);
      // console.log("---测试文件列表", this.fileListTest);
      let formData = new FormData();
      formData.append("file", params.file);
      let data = formData;
      this.$http.post(this.uploadUrl, data).then(res => {
        if (res.status == 200) {
          let url = res.data.data.fileURL;
          let fileList2 = [
            {
              name,
              url
            }
          ];
          this.fileListTest.push({
            name,
            url
          });
          console.log("--fileList", fileList2);
          this.$message({
            type: "success",
            message: res.data.message
          });
          this.$emit("backcall", fileList2);
        }
      });
    },
    isImg(name) {
      var idx = name.indexOf(".");
      if (idx === -1) {
        console.warn("name格式不正确，请检查");
        return;
      }
      var type = name.substr(idx + 1);
      var imgArr = [
        "bmp",
        "jpg",
        "png",
        "tif",
        "gif",
        "pcx",
        "tga",
        "exif",
        "fpx",
        "svg",
        "psd",
        "cdr",
        "pcd",
        "dxf",
        "ufo",
        "eps",
        "ai",
        "raw",
        "WMF",
        "webp"
      ];
      return imgArr.indexOf(type) !== -1 ? true : false;
    }
  }
};
</script>

<style lang="less" scoped>
/*@import "~@/styles/mixin.scss";*/
.upload-container {
  /deep/.el-upload {
    text-align: left;
  }
}
/deep/ .el-upload-list--picture-card .el-upload-list__item {
  width: 100px;
  height: 100px;
  background: #ddd;
}
/deep/ .el-upload-list--picture-card .el-upload-list__item-thumbnail {
  height: auto;
  max-width: inherit;
  width: auto;
}
.upload-file-main {
  margin-top: 20px;
  .upload-file-item {
    display: flex;
    align-items: center;
    margin-bottom: 15px;
    .upload-file-pic {
      width: 48px;
      height: 48px;
      margin-right: 15px;
      img {
        width: 100%;
        height: 100%;
      }
    }
    .upload-file-mid {
      min-width: 0;
      flex: 1;
      .upload-file-name {
        font-size: 16px;
        font-weight: 400;
        color: rgba(40, 40, 40, 1);
        overflow: hidden;
        width: 85%;
        white-space: nowrap;
        text-overflow: ellipsis;
        margin-bottom: 5px;
      }
      .upload-file-size {
        font-size: 14px;
        font-weight: 400;
        color: rgba(146, 146, 146, 1);
      }
    }
    .upload-file-right {
      height: 40px;
      width: 40px;
      line-height: 40px;
      text-align: center;
      font-size: 12px;
      color: #ca313f;
      span {
        cursor: pointer;
      }
      img {
        width: 24px;
        height: 24px;
        animation: rotate 1.1s linear infinite;
        @keyframes rotate {
          from {
            transform: rotate(0deg);
          }
          to {
            transform: rotate(360deg);
          }
        }
      }
    }
  }
}
</style>
